package univ.bme.accounting.beans;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;

import univ.bme.accounting.dao.TransactionDAO;
import univ.bme.accounting.domain.Transaction;
import univ.bme.accounting.domain.User;

@Getter
@Setter

@ManagedBean
@RequestScoped
@NoArgsConstructor
public class ChartMB extends MBUtils{

    private CartesianChartModel categoryModel;
    
    @EJB
	private TransactionDAO  transactiondao; 
    
    @ManagedProperty("#{accountingSessionBean}")
	private AccountingSessionBean accountingSessionBean;
	    
    @ManagedProperty(value="#{param.userid}")
	private int userId;
    
    private boolean invalidUserID;
    
    @ManagedProperty(value="#{param.year}")
    private int year;
    
    List<Integer> years;
    
    List<Transaction> allTransactions;

	@PostConstruct
	public void init() {
		invalidUserID = false;
		checkUserId();
		initYears();
		checkYear();
		allTransactions = transactiondao.findTransactionsForUserAndYear(userId,year);
		categoryModel = new CartesianChartModel();
		createCategoryModel();
	}
	
	private void checkYear() {
		if(!(year>0)){
			year = Calendar.getInstance().get(Calendar.YEAR);
			if(!years.isEmpty()){
				year = Collections.max(years);
			}
		}
	}

	private void initYears() {
		years = transactiondao.findAvailableYears(getUserId());
		Collections.sort(years);
	}

	private void checkUserId(){
		if(!(userId > 0)){
			userId = accountingSessionBean.getUser().getId();
		}
		else{
			User chart_user = accountingSessionBean.getUserdao().find(userId);
			if( chart_user == null || accountingSessionBean.isAccessForbidden(chart_user))
				invalidUserID = true;
		}
	}
	
    public CartesianChartModel getCategoryModel() {
        return categoryModel;
    }

    private void createCategoryModel() {
        Map<Object, Number> monthly = new LinkedHashMap<Object, Number>();
        String key;
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MMM");
        double value = 0;
        for(int i=0; i<12;++i){
        	cal.set(Calendar.YEAR, year);
        	cal.set(Calendar.MONTH, i);
        	cal.set(Calendar.DAY_OF_MONTH,1);
        	monthly.put(formatter.format(cal.getTime()),value);
        }
//        for(Map.Entry<Object, Number> x : monthly.entrySet()){
//        	System.out.println(x.getKey());
//        }
        for(Transaction tr : allTransactions){
        	key = formatter.format(tr.getDate());
        	value = tr.getAmount()*tr.getType();
        	if(monthly.containsKey(key)){
        		value += monthly.get(key).doubleValue();
        		monthly.put(key, value);
        	}
        }
        
        ChartSeries amounts = new ChartSeries();
        amounts.setLabel(bundle.getString("amounts"));
        amounts.setData(monthly);
        categoryModel.addSeries(amounts);
    }
    
    public String yearChanged(){
    	return "transactionStatistics?faces-redirect=true&includeViewParams=true";
    }
}
                    